--协程
--[[
协程不是进程或线程，其执行过程更类似于子例程，或者说不带返回值的函数调用。
一个程序可以包含多个协程，可以对比与一个进程包含多个线程，因而下面我们来比较协程和线我们知道多个线程相对独立，有自己的上下文，切换受系统控制;
而协程也相对独立，有自己的上下文，但是其切换由自己控制，由当前协程切换到其他协程由当前协程来控制。
编程语言Lua从5.0版开始支持协程的概念，极大的扩展了Lua的能力。Lua的协程通过扩展库croutine来实现
可以把协程看成是一个可自行决定调度切换的线程

API:https://www.lua.org/manual/5.4/manual.html#6.2
coroutine.close (co)-----------关闭协程，返回bool
coroutine.create (f)-----------创建协程，传入一个function，返回一个协程句柄
coroutine.isyieldable ([co])-----------判断协程是否是yield 状态
coroutine.resume (co [, val1, ·.]) -----------将挂起态的协程重新激活
coroutine. running ()-----------获取正在运行的协程
coroutine.status----------- (co)获取co句柄对应的协程的状态[suspended(挂起)，running(执行中) , dead(结束)]
coroutine.wrap (f)-----------用function创建一个新的协程
coroutine.yield (.. ) -----------挂起当前协程


Lua的协程是一种类似于线程的概念，它可以实现多个任务的并发执行，但又不同于操作系统的线程。Lua的协程有以下特点：

Lua的协程是协作式的，也就是说，它们需要彼此之间主动让出控制权，才能切换执行。这样可以避免一些线程同步的问题，但也要求程序员更加注意协程之间的协调。
Lua的协程是轻量级的，也就是说，它们不需要太多的系统资源，可以创建很多个协程。每个协程只有自己的栈、局部变量和指令指针，而共享全局变量和其他大部分东西。
Lua的协程是单线程的，也就是说，在任何时刻只有一个协程在运行，其他的协程都处于挂起状态。Lua使用一个全局变量来记录当前运行的协程，所以协程之间不会发生并发冲突。
Lua的协程使用coroutine库来创建和控制。coroutine库提供了以下几个函数：

coroutine.create：创建一个新的协程，并返回一个类型为thread的值，表示该协程。该函数接受一个函数作为参数，表示协程要执行的代码。
coroutine.resume：恢复一个挂起的协程的执行，并传递一些参数给它。该函数接受一个协程和若干个值作为参数。如果是第一次恢复一个协程，那么这些值会作为协程函数的参数；如果是后续恢复一个协程，那么这些值会作为对应yield函数的返回值。该函数返回若干个值，第一个值表示协程是否正常运行，后续的值表示协程返回或yield的值。
coroutine.yield：挂起当前运行的协程，并返回一些值给resume函数。该函数接受若干个值作为参数，表示要返回给resume函数的值。该函数只能在协程中调用，不能在主线程中调用。
coroutine.status：返回一个协程的状态，可以是"suspended"（挂起）、“running”（运行）、“normal”（正常）或"dead"（死亡）。该函数接受一个协程作为参数。
coroutine.running：返回当前运行的协程，如果在主线程中调用，则返回nil。
]]

--创建协程 去银行取钱 取10000块
function func1(a,b)
    print("取10000块",a,b)

    print("拿到凭证排队")

    print("提供银行卡，身份证")

    print("柜员需要去找经理获取授权")
    coroutine.yield()

    print("柜员给我们取钱")

    coroutine.yield()
    print("办其他业务")

    print("取钱结束")

end

--拿到小票凭证
handle=coroutine.create(func1) --小票

print("handle",handle)

print("status",coroutine.status(handle))

--听到叫号了 我们拿着小票去办理业务 执行func1
isOk=coroutine.resume(handle,1,2)
print("isOk",isOk)

print("status2",coroutine.status(handle))
--等待
isOk=coroutine.resume(handle)
print("status3",coroutine.status(handle))

isOk=coroutine.resume(handle)
print("status4",coroutine.status(handle))

--休眠1秒 5.1不支持
function sleep(n)
    local now=os.clock()
    while now+n>=os.clock() do

    end
end

function func1()
    print("func1")
end

function func2()
    print("func2")
end

--i=0
--while true do
--    i=i+1
--    if(i%2==0) then
--        func1()
--    else
--        func2()
--    end
--end

function func1()
    for i = 1, 2 do
        print("func1")
        rs,ii,hello=coroutine.resume(handle2,"哈哈哈")
        print("rs",rs,ii,hello,coroutine.running())
    end
end

function func2(a)
    for i = 1, 2 do
        print("func2",a)
        coroutine.yield(i,"你好")
        print("func2running",coroutine.running())
    end
end

handle1=coroutine.create(func1)
handle2=coroutine.create(func2)

coroutine.resume(handle1)


--生产者消费者模型
--生产者
function prod()
    for i = 1, 3 do
        i=i+1
        print("prod生产",i)
        coroutine.yield(i)
    end
end

--消费者
function consumer()
    for i = 1, 3 do
        local flag,ii=coroutine.resume(prodHandle)
        print("consumer",flag,ii)
    end
end
prodHandle=coroutine.create(prod)
consumerHandle=coroutine.create(consumer)
coroutine.resume(consumerHandle)
